/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package cn.xawl.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.apache.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

/**
 * 返回数据
 *
 * @author Mark sunlightcs@gmail.com
 */
public class R extends HashMap<String, Object> {
	private static final long serialVersionUID = 1L;

	/*
	* 增加R对象的功能：通过get方法可以直接获取一个复杂的对象
	* */

	/**
	 * 封装一个setData方法，为map中添加一个data数据
	 * @param data key为data的数据
	 * @return R对象，方便链式调用
	 */
	public R setData(Object data) {
		put("data", data);
		return this;
	}


	/**
	 * 获取key值为data的对象。主要是为了将data对象转换成需要的类型。（直接调用get方法会将一个PO转换成一个LinkedHashMap）
	 * @param complexType TypeReference，可以转换成复杂对象 for example：
	 * @param <T> 复杂的对象类型
	 * @return 复杂对象类型的data对象
	 */
	public <T> T getData(TypeReference<T> complexType) {
		Object data = get("data"); //由于get到的data会是一个LinkedHashMap，因此需要将对象先转成Json字符串，再通过JSON的parseObject方法转换成指定的类型
		String jsonString = JSON.toJSONString(data);
		return JSON.parseObject(jsonString, complexType); //将一个Json字符串转换成自己想要的类型
	}
	//自定义key的获取
	public <T> T getData(TypeReference<T> complexType, String key) {
		Object data = get(key); //由于get到的data会是一个LinkedHashMap，因此需要将对象先转成Json字符串，再通过JSON的parseObject方法转换成指定的类型
		String jsonString = JSON.toJSONString(data);
		return JSON.parseObject(jsonString, complexType); //将一个Json字符串转换成自己想要的类型
	}

	//简单类型的获取
	public <T> T getData(Class<T> targetClass) {
		Object data = get("data");
		String jsonString = JSON.toJSONString(data);
		return JSON.parseObject(jsonString, targetClass);
	}
	//简单类型的获取  自定义key的获取
	public <T> T getData(Class<T> targetClass, String key) {
		Object data = get(key);
		String jsonString = JSON.toJSONString(data);
		return JSON.parseObject(jsonString, targetClass);
	}

	public R() {
		put("code", 0);
		put("msg", "success");
	}
	
	public static R error() {
		return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常，请联系管理员");
	}
	
	public static R error(String msg) {
		return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
	}
	
	public static R error(int code, String msg) {
		R r = new R();
		r.put("code", code);
		r.put("msg", msg);
		return r;
	}

	public static R ok(String msg) {
		R r = new R();
		r.put("msg", msg);
		return r;
	}
	
	public static R ok(Map<String, Object> map) {
		R r = new R();
		r.putAll(map);
		return r;
	}
	
	public static R ok() {
		return new R();
	}

	@Override
	public R put(String key, Object value) {
		super.put(key, value);
		return this;
	}
}
